package DAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JOptionPane;

import connection.ConnectionManager;
import modelo.Evento;
import modelo.Ingresso;


public class IngressoDAOImp implements IngressoDAO {
	/**
         * Metodo para alterar dados do banco de dados
         */
         /**
          * metodo para inserir ingressos no banco de dados
          */
	private final String INSERT = "INSERT INTO Ingresso(vendido, tipo, id_evento) VALUES (?,?,?)";
	/**
         * metodo para alterar dados dos ingresso no banco de dados
         */
        private final String UPDATE = "UPDATE Ingresso SET vendido=?, tipo=?, id_evento= ? WHERE id_ingresso = ?";
	/**
         * metodo para deletar ingresso no banco de dados
         */
        private final String DELETE = "DELETE from Ingresso WHERE id_ingresso = ?";
	/**
         * metodo para mostrar todo os ingressos
         */
        private final String ALL = "SELECT id_ingresso,vendido,tipo,id_evento FROM Ingresso";
	/**
         * mostrar ingressos pelo identificador
         */
        private final String ID = "SELECT id_ingresso,vendido,tipo,id_evento FROM Ingresso where id_ingresso = ?";
	/**
         * mostrar ingresso pelo tipo de cadeira
         */
        private final String TIPO = "SELECT id_ingresso,vendido,id_evento FROM Ingresso where tipo = ?";
	/**
         * mostrar quantos ingressos foram vendidos
         */
        private final String VENDIDO = "SELECT id_ingresso,tipo,id_evento,vendido FROM Ingresso where vendido = ?";
	/**
         * mostrar os ingresso vendidos
         */
        private final String VENDAEVENTO = "SELECT id_ingresso,tipo,id_evento,vendido FROM Ingresso where vendido = true and id_evento = ?";
	/**
         * mostrar os eventos pelo identificador
         */
        private final String EVENTO = "SELECT id_ingresso,tipo,vendido, id_evento FROM Ingresso where id_evento = ?";
	/**
         * select para limitar a venda de ingresso para que nao haja mais ingresso do que cadeiras
         */
        private final String LIMITE = "SELECT id_ingresso,tipo,vendido,id_evento FROM Ingresso ORDER BY id_ingresso DESC LIMIT ?";
	
        /**
         * variaveis de conex@@o
         */
	private ConnectionManager connectionManager;
	private static Connection connection;
	
	IngressoDAOImp(){
		this.openConnection();
	}
	
	

	@Override
        /**
         * metodo para salvar ingressos
         */
	public Ingresso salvar(Ingresso e) {
		PreparedStatement ps = null;
		try {
			ps = connection.prepareStatement(INSERT);
			
			ps.setObject(1, e.isVendido());
			ps.setObject(2, e.getTipo());
			ps.setObject(3, e.getEvento().getIdEvento());
			
			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(IngressoDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return e;
		
	}
	

	@Override
	public void alterar(Ingresso e) {
		PreparedStatement ps = null;
		try {
			
			ps = connection.prepareStatement(UPDATE);
			
			ps.setObject(1, e.isVendido());
			ps.setObject(2, e.getTipo());
			ps.setObject(3, e.getEvento().getIdEvento());
			ps.setObject(4, e.getIdIngresso());
			

			
			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(IngressoDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		

	}

	@Override
	public void deletar(Ingresso e) {
		try {
			PreparedStatement ps = null;
			ps = connection.prepareStatement(DELETE);
			//3 passe para o PreparedStatement o valor do id que deve ser excluido do banco de dados 
			ps.setObject(1, e.getIdIngresso());
			
			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(IngressoDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		

	}

	@Override
	public List<Ingresso> findAll() {
		List<Ingresso> ingressos = new ArrayList<Ingresso>();
		EventoDAO eventoDAO =  DAOFactory.getEventoDAO();
		List<Evento> eventos = new ArrayList<Evento>();
		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(ALL);
			
			//4 Obtenha uma instancia de resultset
			rs = ps.executeQuery();
			
			while (rs.next()) {
				
				Ingresso ingresso = new Ingresso();
				ingresso.setIdIngresso(rs.getInt("id_ingresso"));
				eventos = eventoDAO.buscaEventoPorId(rs.getInt("id_evento"));
				ingresso.setTipo(rs.getInt("tipo"));
				ingresso.setVendido(rs.getBoolean("vendido"));
				ingresso.setEvento(eventos.get(0));
				ingressos.add(ingresso);
				//5 crie uma instancia de cidade com os dados
				//obtidos do banco e adicione a lista de cidadesf
				
			}

		} catch (SQLException ex) {
			Logger.getLogger(IngressoDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return ingressos;
	}

	@Override
	public boolean isConnectionClose() {
		try {
			return connection.isClosed();
		} catch (SQLException ex) {
			return false;
		}
	}
	
	@Override
	public void openConnection() {
		if ( connectionManager == null ) {
			connectionManager = ConnectionManager.getInstance();
		}
		
		if ( connection == null) {
			connection = connectionManager.getConnection();
		}
		
		if ( isConnectionClose() ) {
			connection = connectionManager.getConnection();
		}
	}

	@Override
	public void closeConnection() {
		if ( connection != null && connectionManager != null) {
			if ( ! this.isConnectionClose() ) {
				connectionManager.closeConnection(connection);
			}
		}
	}

	@Override
	public List<Ingresso> buscaIngressoPorId(Ingresso ingresso) {
		List<Ingresso> ingressos = new ArrayList<Ingresso>();
		EventoDAO eventoDAO =  DAOFactory.getEventoDAO();
		List<Evento> eventos = new ArrayList<Evento>();
		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(ID);
			ps.setObject(1, ingresso.getIdIngresso());
			
			
			//4 Obtenha uma instancia de resultset
			rs = ps.executeQuery();
			
			while (rs.next()) {
				
				
				ingresso.setIdIngresso(rs.getInt("id_ingresso"));
				eventos = eventoDAO.buscaEventoPorId(rs.getInt("id_evento"));
				ingresso.setTipo(rs.getInt("tipo"));
				ingresso.setVendido(rs.getBoolean("vendido"));
				ingresso.setEvento(eventos.get(0));
				ingressos.add(ingresso);
				//5 crie uma instancia de cidade com os dados
				//obtidos do banco e adicione a lista de cidadesf
				
			}

		} catch (SQLException ex) {
			Logger.getLogger(IngressoDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return ingressos;
	}

	@Override
	public List<Ingresso> buscaIngressoPorTipo(Ingresso ingresso) {
		List<Ingresso> ingressos = new ArrayList<Ingresso>();
		EventoDAO eventoDAO =  DAOFactory.getEventoDAO();
		List<Evento> eventos = new ArrayList<Evento>();
		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(TIPO);
			ps.setObject(1, ingresso.getTipo());
			
			
			//4 Obtenha uma instancia de resultset
			rs = ps.executeQuery();
			
			while (rs.next()) {
				
				
				ingresso.setIdIngresso(rs.getInt("id_ingresso"));
				eventos = eventoDAO.buscaEventoPorId(rs.getInt("id_evento"));
				ingresso.setTipo(rs.getInt("tipo"));
				ingresso.setVendido(rs.getBoolean("vendido"));
				ingresso.setEvento(eventos.get(0));
				ingressos.add(ingresso);
				//5 crie uma instancia de cidade com os dados
				//obtidos do banco e adicione a lista de cidadesf
				
			}

		} catch (SQLException ex) {
			Logger.getLogger(IngressoDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return ingressos;
	}

	@Override
	public List<Ingresso> buscaIngressoVendido(Ingresso ingresso) {
		List<Ingresso> ingressos = new ArrayList<Ingresso>();
		EventoDAO eventoDAO =  DAOFactory.getEventoDAO();
		List<Evento> eventos = new ArrayList<Evento>();
		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(VENDIDO);
			ps.setObject(1, ingresso.isVendido());
			
			
			//4 Obtenha uma instancia de resultset
			rs = ps.executeQuery();
			
			while (rs.next()) {
				
				
				ingresso.setIdIngresso(rs.getInt("id_ingresso"));
				eventos = eventoDAO.buscaEventoPorId(rs.getInt("id_evento"));
				ingresso.setTipo(rs.getInt("tipo"));
				ingresso.setVendido(rs.getBoolean("vendido"));
				ingresso.setEvento(eventos.get(0));
				ingressos.add(ingresso);
				//5 crie uma instancia de cidade com os dados
				//obtidos do banco e adicione a lista de cidadesf
				
			}

		} catch (SQLException ex) {
			Logger.getLogger(IngressoDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return ingressos;
	}



	@Override
	public List<Ingresso> buscaIngressoEvento(Ingresso ingresso) {
		List<Ingresso> ingressos = new ArrayList<Ingresso>();
		EventoDAO eventoDAO =  DAOFactory.getEventoDAO();
		List<Evento> eventos = new ArrayList<Evento>();
		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(VENDAEVENTO);
			ps.setObject(1, ingresso.getEvento().getIdEvento());
			
			
			//4 Obtenha uma instancia de resultset
			rs = ps.executeQuery();
			
			while (rs.next()) {
				
				
				ingresso.setIdIngresso(rs.getInt("id_ingresso"));
				eventoDAO.openConnection();
				eventos = eventoDAO.buscaEventoPorId(rs.getInt("id_evento"));
				ingresso.setTipo(rs.getInt("tipo"));
				ingresso.setVendido(rs.getBoolean("vendido"));
				ingresso.setEvento(eventos.get(0));
				ingressos.add(ingresso);
				//5 crie uma instancia de cidade com os dados
				//obtidos do banco e adicione a lista de cidadesf
				
			}

		} catch (SQLException ex) {
			Logger.getLogger(IngressoDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return ingressos;
	}



	@Override
	public List<Ingresso> buscaIngressoUltimos(int limite) {
		List<Ingresso> ingressos = new ArrayList<Ingresso>();
		EventoDAO eventoDAO =  DAOFactory.getEventoDAO();
		List<Evento> eventos = new ArrayList<Evento>();
		Ingresso ingresso = new Ingresso();
		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(LIMITE);
			ps.setObject(1, limite);
			
			
			//4 Obtenha uma instancia de resultset
			rs = ps.executeQuery();
			
			while (rs.next()) {
				
				
				ingresso.setIdIngresso(rs.getInt("id_ingresso"));
				eventoDAO.openConnection();
				eventos = eventoDAO.buscaEventoPorId(rs.getInt("id_evento"));
				ingresso.setTipo(rs.getInt("tipo"));
				ingresso.setVendido(rs.getBoolean("vendido"));
				ingresso.setEvento(eventos.get(0));
				ingressos.add(ingresso);
				//5 crie uma instancia de cidade com os dados
				//obtidos do banco e adicione a lista de cidadesf
				
			}

		} catch (SQLException ex) {
			Logger.getLogger(IngressoDAOImp.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			this.closeConnection();
		}
		return ingressos;
	
	}

}
